package com.starxg.m3u8.controller;

import com.starxg.m3u8.config.AppConfig;
import com.starxg.m3u8.gui.LoadingDialog;
import com.starxg.m3u8.gui.Promise;
import com.starxg.m3u8.utils.HttpUtils;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.util.StringConverter;
import javafx.util.converter.IntegerStringConverter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import com.starxg.m3u8.config.ApplicationConfig;
import com.starxg.m3u8.config.WindowConfig;

import java.net.Proxy;

/**
 * MainController
 *
 * @author huangxingguang@lvmama.com
 * @date 2020-08-12 22:57
 */
@Slf4j
public class ConfigController extends BaseController {

    @FXML
    private TextField txtHttpRetryCount;
    @FXML
    private Button btnProxyTestConnection;
    @FXML
    private VBox vbProxy;
    @FXML
    private ComboBox<String> cbProxyType;
    @FXML
    private TextField txtProxyPassword;
    @FXML
    private TextField txtProxyUsername;
    @FXML
    private TextField txtProxyHost;
    @FXML
    private TextField txtProxyPort;
    @FXML
    private CheckBox cbAutoMergeTs;
    @FXML
    private CheckBox cbDeleteTs;
    @FXML
    private TextArea taHttpHeader;
    @FXML
    private ComboBox<Integer> cbConnections;
    private ApplicationConfig config = ApplicationConfig.getInstance();

    @Override
    public void initView() {
        cbConnections.getItems().add(5);
        cbConnections.getItems().add(10);
        cbConnections.getItems().add(15);
        cbConnections.getItems().add(20);
        cbConnections.getItems().add(30);
        cbConnections.getItems().add(AppConfig.HTTP_MAX_CONNECTIONS);
        cbConnections.getEditor().setTextFormatter(new TextFormatter<>(new IntegerStringConverter()));
        txtHttpRetryCount.setTextFormatter(new TextFormatter<>(new IntegerStringConverter()));

        cbProxyType.getItems().add(WindowConfig.PROXY_NONE);
        cbProxyType.getItems().add(Proxy.Type.HTTP.name());
        cbProxyType.getItems().add(Proxy.Type.SOCKS.name());

        txtProxyPort.setTextFormatter(new TextFormatter<>(new IntegerStringConverter()));

        vbProxy.setDisable(WindowConfig.PROXY_NONE.equals(config.getWindow().getProxyType()));
    }

    @Override
    public void initEvent() {
        AppConfig app = config.getApp();
        WindowConfig window = config.getWindow();
        cbConnections.setOnAction(e -> app.setHttpConnections(cbConnections.getValue()));
        taHttpHeader.textProperty().bindBidirectional(app.requestHeaderProperty());
        cbAutoMergeTs.selectedProperty().bindBidirectional(app.autoMergeTsProperty());
        cbDeleteTs.selectedProperty().bindBidirectional(app.autoDeleteTsProperty());
        txtHttpRetryCount.focusedProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue) {
                int count = NumberUtils.toInt(txtHttpRetryCount.getText(), -1);
                config.getApp().setHttpRetryCount(count < 0 ? -1 : count);
            }
        });
        cbConnections.setConverter(new StringConverter<>() {
            @Override
            public String toString(Integer num) {
                return (num == null || num < 1) ? "1" : num.toString();
            }

            @Override
            public Integer fromString(String text) {
                int num = NumberUtils.toInt(text, 1);
                return (num < 1 || num > AppConfig.HTTP_MAX_CONNECTIONS) ? 1 : num;
            }
        });

        txtProxyPort.textProperty().bindBidirectional(window.proxyPortProperty());
        txtProxyPassword.textProperty().bindBidirectional(window.proxyPasswordProperty());
        txtProxyHost.textProperty().bindBidirectional(window.proxyHostProperty());
        txtProxyUsername.textProperty().bindBidirectional(window.proxyUsernameProperty());
        cbProxyType.valueProperty().bindBidirectional(window.proxyTypeProperty());
        cbProxyType.valueProperty().addListener((observable, oldValue, newValue) -> vbProxy
                .setDisable(WindowConfig.PROXY_NONE.equals(cbProxyType.getValue())));

        btnProxyTestConnection.setOnAction(e -> {

            String prompt = prompt("http(s)://", StringUtils.EMPTY);
            if (StringUtils.isBlank(prompt)) {
                return;
            }

            LoadingDialog dialog = new LoadingDialog("测试连接中");
            new Promise<Void>((resolve, reject) -> {
                try {
                    String s = HttpUtils.get(prompt);
                    log.info("测试连接成功。response：{}", s);
                    resolve.accept(null);
                } catch (Exception ex) {
                    log.error(ex.getMessage(), ex);
                    reject.accept(ex);
                }
            }).then(ex -> alert("连接成功")).error(ex -> alert("测试失败。原因：" + ex.getMessage(), Alert.AlertType.ERROR))
                    .complete(dialog::closeNow);
            dialog.showAndWait();
        });

    }

    @Override
    public void initData() {
        cbConnections.setValue(config.getApp().getHttpConnections());
        cbProxyType.setValue(config.getWindow().getProxyType());
        txtHttpRetryCount.setText(String.valueOf(config.getApp().getHttpRetryCount()));
    }

}
